import 'dart:async';

import 'package:flutter/material.dart';

class CountdownView extends StatefulWidget {
  final Duration duration;
  final Duration interval;
  final void Function()? onFinish;
  final Widget Function(BuildContext context, Duration remaining) builder;
  final Widget? overtimeWidget;

  final bool isStartWhenInit;

  CountdownView(this.duration, this.interval, this.builder, this.overtimeWidget,
      {this.isStartWhenInit = false, this.onFinish, Key? key})
      : super(key: key);

  @override
  _CountdownViewState createState() => _CountdownViewState();
}

class _CountdownViewState extends State<CountdownView> {
  Timer? _timer;
  late Duration _duration;

  late CountdownController _countdownController = CountdownController();

  bool exceed = false; //是否超过倒计时

  bool isFirstCallback = false;

  @override
  void initState() {
    super.initState();
    _duration = widget.duration;
    if (_duration.inSeconds <= 0) {
      //直接显示超时
      exceed = true;
    } else {
      _countdownController.addListener(() {
        if (_countdownController.control ==
            CountdownController.ControllerStart) {
          startTimer();
        }
      });
      if (widget.isStartWhenInit) {
        startTimer();
      }
    }
  }

  void startTimer() {
    _timer = Timer.periodic(widget.interval, timerCallback);

    _countdownController.state = CountdownController.StateRunning;
  }

  void timerCallback(Timer timer) {
    setState(() {
      if (_duration.inSeconds == 0) {
        _countdownController.state = CountdownController.StateWaiting;

        _duration = widget.duration;

        timer.cancel();
        if (widget.onFinish != null) {
          widget.onFinish!();
        }
      } else {
        _duration = _duration - widget.interval;
      }
    });
  }

  @override
  void didUpdateWidget(CountdownView oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.duration != widget.duration) {
      _duration = widget.duration;
      //直接回调
      if (_duration.inSeconds <= 0) {
        exceed = true;
        _countdownController.state = CountdownController.StateWaiting;
        _timer?.cancel();
      } else {
        exceed = false;
      }
      if (mounted) setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    if (exceed) {
      return widget.overtimeWidget ?? widget.builder(context, _duration);
    }
    return widget.builder(context, _duration);
  }

  @override
  void dispose() {
    _timer?.cancel();
    _countdownController.dispose();
    super.dispose();
  }
}

class CountdownController extends ChangeNotifier {
  static const int StateWaiting = 0;
  static const int StateRunning = 1;

  static const int ControllerStart = 10;

  int state = StateWaiting;

  late int control;

  void start() {
    control = ControllerStart;

    notifyListeners();
  }
}
